package ru.evreke.service

import Game
import io.ktor.server.websocket.*
import io.ktor.websocket.*
import org.slf4j.LoggerFactory
import java.util.concurrent.ConcurrentHashMap

class ServerState(
    override val gameIdToPendingGame: ConcurrentHashMap<String, Game> = ConcurrentHashMap(),
    override val gameIdToActiveGame: ConcurrentHashMap<String, Game> = ConcurrentHashMap(),
    override val playerIdToWebSocketSession: ConcurrentHashMap<String, DefaultWebSocketServerSession>
    = ConcurrentHashMap()
) : State {

    private val logger = LoggerFactory.getLogger("ServerState")
    override fun getPendingGames(): ConcurrentHashMap<String, Game> {
        return gameIdToPendingGame
    }

    override fun getActiveGames(): ConcurrentHashMap<String, Game> {
        return gameIdToActiveGame
    }

    override fun getWebsocketSessions(): ConcurrentHashMap<String, DefaultWebSocketServerSession> {
        return playerIdToWebSocketSession
    }

    override fun addPendingGame(gameId: String, game: Game) {
        if (!gameIdToPendingGame.contains(gameId)) {
            gameIdToPendingGame[gameId] = game
        } else {
            logger.error("Game with id=$gameId is not exists")
        }
    }

    override fun addActiveGame(gameId: String, game: Game) {
        removePendingGame(gameId)
        gameIdToActiveGame[gameId] = game
    }

    override fun addWebsocketSession(playerId: String, webSocketSession: DefaultWebSocketServerSession) {
        if (!playerIdToWebSocketSession.containsKey(playerId)) {
            playerIdToWebSocketSession[playerId] = webSocketSession
        } else {
            logger.error("Player with id=$playerId already connected and can't connect twice")
        }
    }

    override fun removePendingGame(gameId: String) {
        gameIdToPendingGame[gameId]
    }

    override fun removeActiveGame(gameId: String) {
        gameIdToActiveGame[gameId]
    }

    override suspend fun removeWebsocketSession(playerId: String) {
        playerIdToWebSocketSession[playerId].also {
            it?.close() ?: error("Socket session for player=$playerId wasn't found")
        }
    }
}